package com.zhonghui.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;

import com.zhonghui.common.core.utils.JwtUtils;
import com.zhonghui.common.core.utils.RedisUtils;
import com.zhonghui.common.core.result.FwResult;
import com.zhonghui.dto.*;
import com.zhonghui.mapper.UserMapper;
import com.zhonghui.model.User;
import com.zhonghui.service.UserService;
import com.zhonghui.vo.UserListVo;
import com.zhonghui.vo.UserRecordVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.internet.MimeMessage;
import java.util.*;

import static com.zhonghui.common.core.constant.FwConstants.USER_LOGIN_TOKEN;

/**
 * @description 用户信息-业务实现
 * @author zhonghui
 * @date 2020-11-29
 */
@Service
@Slf4j
public class UserServiceImpl  implements UserService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private  UserMapper userMapper;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from="";

    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public FwResult<Map<String, Object>> passwordLogin(PhoneLoginDto phoneLoginDto) {

        User mobileUser = userMapper.getUserByPhone(phoneLoginDto.getPhone());
        if (mobileUser.getStatus() == 0){
            return FwResult.failedMsg("用户已被禁用，请联系管理员");
        }
        if(ObjectUtil.isNotNull(mobileUser)){
            if(mobileUser.getPassword().equals(SecureUtil.md5(phoneLoginDto.getPassword()))){
                Map<String,Object> map=new HashMap<>();
                map.put("userInfo",mobileUser);
                String key= jwtUtils.sign(map);
                String userCache = JSONUtil.toJsonStr(mobileUser);
                redisUtils.set(USER_LOGIN_TOKEN +key,userCache,360000);
                redisUtils.set("userId",mobileUser.getId().toString(),360000);
                map.put("Authorization",key);

                return FwResult.ok(map);
            }else{
                return FwResult.failedMsg("密码错误");
            }
        }
        return FwResult.failedMsg("认证错误");
    }

    @Override
    public FwResult emailLogin(VerifyEmailDto emailDto){
        User emailUser = userMapper.getUserByEmail(emailDto.getEmail());
        if(ObjectUtil.isNotNull(emailUser)){
            if(emailUser.getStatus() == 0){
                return FwResult.failedMsg("用户已被禁用，请联系管理员");
            }
//            获取验证码
            String code = redisUtils.get("verification_code");
            if(code.equals(emailDto.getCode())){
                Map<String,Object> map=new HashMap<>();
                map.put("userInfo",emailUser);
                String key= jwtUtils.sign(map);
                String userCache = JSONUtil.toJsonStr(emailUser);
                redisUtils.set(USER_LOGIN_TOKEN +key,userCache,360000);
                redisUtils.set("userId",emailUser.getId().toString(),360000);
                map.put("Authorization",key);
                return FwResult.ok(map);
            }else {
                return FwResult.failedMsg("邮箱或验证码错误");
            }
        }
        return FwResult.failedMsg("邮箱或验证码错误");
    }

    @Override
    public FwResult resetPassword(ResetPasswordDto resetPassword) {
        if(StrUtil.isNotBlank(resetPassword.getEmail())){
            User user = userMapper.getUserByEmail(resetPassword.getEmail());
            if(ObjectUtil.isNotNull(user)){
                if(user.getStatus() == 0){
                    return FwResult.failedMsg("用户已被禁用，请联系管理员");
                }
                if(userMapper.updateUser(user) > 0){
                    return FwResult.okMsg("密码重置成功,密码为123456");
                }
            }
        }
        return FwResult.failedMsg("邮箱或验证码错误");
    }

    @Override
    public FwResult enableUser(EnableUserDto enableUserDto) {
        User user = userMapper.getUserByEmail(enableUserDto.getEmail());
        if(ObjectUtil.isNotNull(user)){
            if(user.getStatus() == 0){
                user.setStatus(1);
                if(userMapper.updateUser(user) > 0){
                    return FwResult.okMsg("用户启用成功");
                }
            }else {
                user.setStatus(0);
                if(userMapper.updateUser(user) > 0){
                    return FwResult.okMsg("用户禁用成功");
                }
            }
        }
        return FwResult.failedMsg("邮箱或验证码错误");
    }

    @Override
    public FwResult<User> logout(String token) {
        if(StrUtil.isNotBlank(token)){
            redisUtils.del(USER_LOGIN_TOKEN+token);
        }
        return FwResult.okMsg("退出成功");
    }

    @Override
    public FwResult<Object> getUserList( PageDto pageDto){
        List<User> users = userMapper.getUserList();
        List<UserRecordVo> userRecordVos = new ArrayList<>();
        for (User user : users){
            UserRecordVo userRecordVo = UserRecordVo.builder()
                    .id(user.getId())
                    .username(user.getUserName())
                    .email(user.getEmail())
                    .phone(user.getPhone())
                    .status(user.getStatus())
                    .createTime(user.getCreateTime())
                    .nickname(user.getNickname())
                    .build();
            userRecordVos.add(userRecordVo);
        }
        if(ObjectUtil.isNotNull(userRecordVos)){
            UserListVo userListVo= UserListVo.builder()
                    .records(userRecordVos)
                    .total(userRecordVos.size())
                    .current(pageDto.getCurrent())
                    .pages(1)
                    .size(pageDto.getSize())
                    .searchCount(true)
                    .build();

            return FwResult.ok(userListVo);
        }

        return FwResult.ok();
    }

    /**
     * 生成邮箱验证码
     */
    @Override
    public void generateCode(String to, String name) {
        try{
        //           随机生成6位验证码
        String code = String.valueOf((int)(Math.random() * 900000) + 100000);
//            将验证码保存到redis中,验证码有效时间为60s
        redisUtils.set("verification_code",code,60000);
            log.info("验证码：" + code);
        Context context = new Context();
        context.setVariable("name", name);
        context.setVariable("code", code);
        // 解析模板并替换变量
        String htmlBody = templateEngine.process("mail.html", context);
//                创建邮件
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject("Verification Code");
        helper.setText(htmlBody, true);
        // 发送邮件
        mailSender.send(message);

    }catch (Exception  e){
        log.error("邮件发送失败",e);
    }

}

    @Override
    public FwResult register(UserMailRegisterDto user) {
        if (userMapper.getUserByEmail(user.getEmail()) != null){
            return FwResult.failedMsg("邮箱已被注册");
        }
        if (userMapper.getUserByPhone(user.getPhone()) != null){
            return FwResult.failedMsg("手机号已被注册");
        }
        if (userMapper.createUser(User.builder()
                .email(user.getEmail())
                .nickname(user.getNickname())
                .password(SecureUtil.md5(user.getPassword()))
                .phone(user.getPhone())
                .userName(user.getUserName())
                .build()) > 0){
            return FwResult.okMsg("注册成功");
        }
        return FwResult.failedMsg("注册失败");
    }

    @Override
    public FwResult verifyMail(VerifyEmailDto code) {
        String rCode = redisUtils.get("verification_code");
        if (StrUtil.isBlank(rCode)){
            return FwResult.failedMsg("验证码已过期");
        }
        if (!rCode.equals(code.getCode())){
            return FwResult.failedMsg("验证码错误");
        }

        return FwResult.okMsg("验证通过");
    }


}
